#ifndef PLAYER_CHARACTER_H
#define PLAYER_CHARACTER_H

#include "Character.h"
#include "AllignmentEnum.h"
#include "NonPlayerCharacter.h"
#include "../ISpellReceiver.h"
#include "../ISpell.h"
#include "qimage.h"

#include <vector>
#include <iostream>
#include <memory>

using namespace std;

class MagicObject;

class PlayerCharacter : public Character, public ISpellReceiver
{
public: 
	PlayerCharacter();
	PlayerCharacter(string iCharacterName, string iCharacterDescription, unsigned int iCharacterStrengthValue, unsigned int iCharacterCraftValue);
	virtual ~PlayerCharacter();

	// Getters
	inline unsigned int getStrengthCounter(void) const {return mStrengthCounter; };
	inline unsigned int getLifeCounter(void) const {return mLifeCounter; };
	inline unsigned int getCraftCounter(void) const {return mCraftCounter; };
	inline unsigned int getGoldenCoinNumberInPossession(void) const {return mGoldCoinsInPossession; };
	inline unsigned int getFateTokenNumberInPossession(void) const {return mFateTokensInPossession; }
	inline Allignment::Allignment getAllignmentSide(void) const {return mAllignmentSide; };
	inline bool isCharacterToad(void) const {return mIsToad; };
	inline virtual bool isToad(void) const { return mIsToad; };
	const QImage * getPicture(void) const override;
	virtual vector<ISpell *>& getSpells(void) { return mSpells; };
	
	// Getters for the derived values
	virtual unsigned int getTotalCharacterStrength(void) const;
	virtual unsigned int getTotalCharacterCraft(void) const;

	// Setters
	inline void setStrengthCounter(const unsigned int iCharacterStrengthCounter) {mStrengthCounter = iCharacterStrengthCounter; };
	inline void setLifeCounter(const unsigned int iCharacterLifeCounter) {mLifeCounter = iCharacterLifeCounter; };
	inline void setCraftCounter(const unsigned int iCharacterCraftCounter) {mCraftCounter = iCharacterCraftCounter; };
	inline void setGoldenCoinNumberInPossession(const unsigned int iGoldenCoinsInPossession) {mGoldCoinsInPossession = iGoldenCoinsInPossession; };
	inline void setFateTokenNumberInPossession(const unsigned int iFateTokensInPossession) {mFateTokensInPossession = iFateTokensInPossession; }
	inline Allignment::Allignment setAllignmentSide(const Allignment::Allignment iAllignmentSide) {mAllignmentSide = iAllignmentSide; };
	inline void isCharacterToad(const bool iIsCharacterToad) {mIsToad = iIsCharacterToad; };
	inline vector<MagicObject *> getMagicObjects(void) const {return mMagicObjects; };
	inline vector<NonPlayerCharacter *> getFollowers(void) const {return mFollowers; };
	inline void setToad(bool iToad) { mIsToad = iToad; if(iToad) toadTurnsLeft = 3; };

	// Additional modifiers
	inline void addFollower(NonPlayerCharacter * iFollower) { mFollowers.push_back(iFollower); };
	inline void addMagicObject(MagicObject * iMagicObject) {mMagicObjects.push_back(iMagicObject); };
	inline void loseAllFollowers(void) {mFollowers.clear(); };
	inline void lostAllMagicObjects(void) {mMagicObjects.clear(); };
	inline void updateToad(void) { if (toadTurnsLeft-- <= 0) setToad(false); };
	inline void addSpell(ISpell * iSpell) { mSpells.push_back(iSpell); };

	// Spell modifiers
	virtual inline void doubleStrengthValue(void) {setCharacterStrengthValue(getStrengthValue() * 2); };
	virtual inline void addStrengthCounter(void) { setStrengthCounter(getStrengthCounter() + 1); };
	virtual inline void craftToStrength(void) {setCharacterStrengthValue(getStrengthValue()+getTotalCharacterCraft()); };


private:

	vector< NonPlayerCharacter * > mFollowers;
	vector< MagicObject * > mMagicObjects;
	vector<ISpell *> mSpells;
	
	unsigned int mStrengthCounter;
	unsigned int mLifeCounter;
	unsigned int mCraftCounter;
	unsigned int mGoldCoinsInPossession;
	unsigned int mFateTokensInPossession;
	Allignment::Allignment mAllignmentSide; 
	bool mIsToad;

	QImage toad;
	int toadTurnsLeft;
};

#endif